package com.rc.scripting.plugin;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Date;

import javax.script.CompiledScript;
import javax.script.ScriptException;

/**
 * <p>
 * This is a simple implementation of interface <code>Plugin</code>, which
 * can be used in most case where need a plug-in in application. Of course
 * one can implements their own <code>Plugin</code>.
 * </p>
 * @author juntao.qiu@gmail.com
 * @date 2010-5-13
 */
public class SimplePlugin implements Plugin{
	private CompiledScript compiledScript;
	private File file;
	private String name;
	private String desc;
	
	private String status;
	
	private Date lastModified;
	
	/*
	 * parse the script name like this:
	 * "scripts/json.js" will returns "json"
	 * "test.js" will returns "test"
	 * "./test.js" will returns "test"
	 * "scripts/test" will returns "test"
	 */
	private static String parseScriptName(String name){
		String scriptName;
		int slash = name.lastIndexOf("/");
		if(slash < 0){
			scriptName = name.substring(0);
		}else{
			scriptName = name.substring(slash+1);
		}
		
		int dot = scriptName.lastIndexOf(".");
		if(dot >= 0){
			scriptName = scriptName.substring(0, dot);
		}
		
		return scriptName;
	}
	
	public SimplePlugin(String file){
		this(file, parseScriptName(file));
	}
	
	public SimplePlugin(String file, String name){
		this(file, name, parseScriptName(file));
	}
	
	public SimplePlugin(String file, String name, String desc){
		this.file = new File(file);
		this.name = name;
		this.desc = desc;
		this.compile(this.file);
	}
	
	/**
	 * compile the script-file into an <code>CompiledScript</code> object
	 * @return
	 */
	public CompiledScript compile(File file){
		Date scriptDate = new Date(file.lastModified());
		if(lastModified == null || scriptDate.after(lastModified)){
			Reader reader = null;
			try {
				reader = new FileReader(file);
				compiledScript = 
					RuntimeEnv.getInstance().getCompilableEngine().compile(reader);
				lastModified = scriptDate;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (ScriptException e) {
				e.printStackTrace();
			}finally{
				if(reader != null){
					try {
						reader.close();
					} catch (IOException e) {}	
				}
			}
		}
		
		this.status = Plugin.STATUS_LOADED;
		
		return compiledScript;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.rc.json.plugin.Plugin#activate()
	 */
	public Object activate() {
		Object result = null;
		try {
			result = compile(this.file).eval();
		} catch (ScriptException e) {
			e.printStackTrace();
		}
		this.status = Plugin.STATUS_ACTIVE;
		return result;
	}

	/*
	 * (non-Javadoc)
	 * @see com.rc.json.plugin.Plugin#getDescription()
	 */
	public String getDescription() {
		return this.desc;
	}

	/*
	 * (non-Javadoc)
	 * @see com.rc.json.plugin.Plugin#getName()
	 */
	public String getName() {
		return this.name;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.rc.json.plugin.Plugin#getStatus()
	 */
	public String getStatus(){
		return this.status;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.rc.json.plugin.Plugin#activate(com.rc.json.plugin.Context)
	 */
	public Object activate(Context context) {
		Object result = null;
		try {
			result = compile(this.file).eval(context);
		} catch (ScriptException e) {
			e.printStackTrace();
		}
		this.status = Plugin.STATUS_ACTIVE;
		return result;
	}
	
}
